<HTML><HEAD> <!-- -------------- RPN Calculator -------------- --> <SCRIPT LANGUAGE="JavaScript"><!-- hide from old browsers /* THE JAVASCRIPT COOKBOOK by Erica Sadun, webrx@mindspring.com Copyright (c)1998 by Charles River Media. All Rights Reserved. This applet can only be re-used or modifed by license holders of the JavaScript Cookbook CD-ROM. Credit must be given in the source code and this copyright notice must be maintained. If you do not hold a license to the JavaScript Cookbook, you may NOT duplicate or modify this code for your own use. Use at your own risk. No warranty is given or implied of the suitability of this applet for any specific application. Neither Erica Sadun nor Charles River Media will be held responsible for any unwanted effects due to the use of this applet or any derivative. */ // Create an Array function createArray(n) { this.length = n; for (var i = 0; i < n; i++) {this[i] = 0} return this } // Initialize Global Variables stack = createArray(20) // 20 should be big enough sktop = 0 // Top of the Stack entry = "0" // Current Entry restart = true // Number: overwrite (restart) or add (!restart) // Show the Stack function showstack(aform) { var answer="" for (var i = 0; i < sktop; i++) answer = stack[i] + ": " + answer aform.stack.value = answer } // Handle a Number Tap function tap(aform, c) { if (restart) // Either new start or stack just pushed { aform.answer.value = c restart = false } else if (c == '.') // Add decimal only if unique { if (aform.answer.value.indexOf(".") < 0) aform.answer.value += "." } else if (aform.answer.value == '0') // Zero gets overwritten { aform.answer.value = c } else aform.answer.value += c // Add digit } // Clear the Current Entry function clear(aform) { aform.answer.value = '0' restart = true } // Handle a Math Request function req(aform, afunction) { if (sktop == 0) // push new value and function { // allow unary operations, default to (0 op Number) entry = eval("0" + afunction + aform.answer.value) // update the answer and prepare for new number or "enter" aform.answer.value = entry restart = true showstack(aform) } else // pop and evaluate { var v = stack[sktop-1] // pop stack sktop-- // derive new answer var answer = eval(v + afunction + aform.answer.value) // display it aform.answer.value = "" + answer // reset for a new number and show stack entry ="" restart = true showstack(aform) } } // Press the All Clear button function ac(aform) { // all clear aform.answer.value = "0" // reset answer line restart = true // prepare for a new number entry = "" sktop = 0 // reset stack showstack(aform) // show empty stack } // Push the Stack function push(aform) { stack[sktop] = ""+aform.answer.value // push onto stack sktop++ // increase top of stack restart = true // prepare for new number entry = "" aform.answer.value = "0" // reset input line showstack(aform) // show stack } <!-- done hiding --></SCRIPT></HEAD> <BODY bgcolor="ffffff" link="0000ff" vlink="770077"> <FONT COLOR="007777"><H1><IMG SRC="../GRAFX/UTENS.JPG" WIDTH=80 HEIGHT=50 ALIGN = CENTER>RPN Calculator</H1></FONT> <BLOCKQUOTE> <FONT COLOR="770000"> Try out this reverse polish notation calculator. It works like some popular scientific calculators. Instead of tapping 5 + 3, you tap "5", "Enter", "3", "+". Try these:<ul></FONT> <li> <b>Approximate PI</b>: tap "2", tap "2", tap "Enter", tap "7" and tap "/" <br><tt><FONT SIZE=2>[Postfix: 22 7 /]</FONT></tt> <li> <b>Calculate (5+3)/(4-2)</b>: tap "5", tap "Enter", tap "3", tap "+", tap "Enter", tap "4", tap "Enter", tap "2", tap "-", tap "/". <br><tt><FONT SIZE=2>[Postfix: 5 3 + 4 2 - /]</FONT></tt> </ul> </BLOCKQUOTE> <BR><BR> <CENTER><FORM><TABLE BORDER=1> <TR> <TD align=center colspan=4><input type="text" name="stack" value="0" size=23>: STACK</TD> </TR> <TR> <TD align=center colspan=4><input type="text" name="answer" value="0" size=30></TD> </TR> <TR> <TD align=center ><input type="button" value=" 7 " onClick="tap(this.form,'7')"></TD> <TD align=center ><input type="button" value=" 8 " onClick="tap(this.form,'8')"></TD> <TD align=center ><input type="button" value=" 9 " onClick="tap(this.form,'9')"></TD> <TD align=center ><input type="button" value=" / " onClick="req(this.form,' / ')"></TD> </TR> <TR> <TD align=center ><input type="button" value=" 4 " onClick="tap(this.form,'4')"></TD> <TD align=center ><input type="button" value=" 5 " onClick="tap(this.form,'5')"></TD> <TD align=center ><input type="button" value=" 6 " onClick="tap(this.form,'6')"></TD> <TD align=center ><input type="button" value=" * " onClick="req(this.form,' * ')"></TD> </TR> <TR> <TD align=center ><input type="button" value=" 1 " onClick="tap(this.form,'1')"></TD> <TD align=center ><input type="button" value=" 2 " onClick="tap(this.form,'2')"></TD> <TD align=center ><input type="button" value=" 3 " onClick="tap(this.form,'3')"></TD> <TD align=center ><input type="button" value=" - " onClick="req(this.form,' - ')"></TD> </TR> <TR> <TD align=center ><input type="button" value=" C " onClick="clear(this.form)"></TD> <TD align=center ><input type="button" value=" 0 " onClick="tap(this.form,'0')"></TD> <TD align=center ><input type="button" value=" . " onClick="tap(this.form,'.')"></TD> <TD align=center ><input type="button" value=" + " onClick="req(this.form, ' + ')"></TD> </TR> <TR> <TD align=center colspan=3 align=right> <input type="button" value=" Enter " onClick="push(this.form)"></TD> <TD align=center ><input type="button" value=" AC " onClick="ac(this.form)"></TD> </TR> </TABLE></FORM></CENTER> <BR><BR> <FONT COLOR="007777"><H2>Discussion</H2></FONT> <FONT SIZE=4> Unlike the previous calculator example, this RPN calculator stores arguments in a stack. Operators are entered in postfix order using reverse polish notation. Each operation pops the stack by one. The results are shown in the answer line and must be manually pushed back onto the stack with the "Enter" key. A simple array called <FONT COLOR="770000">stack</FONT> holds the stack data. The variable <FONT COLOR="770000">sktop</FONT> points to the top of the stack. The function below demonstrates a stack push. After each push, the answer line is reset to zero and the stack line is updated. </FONT> <FONT COLOR="770000"><PRE> function push(aform) { // push onto stack stack[sktop] = ""+aform.answer.value // increase the top of the stack sktop++ // reset the answer to zero aform.answer.value = "0" // show the new stack showstack(aform) // reset for entering a new number restart = true entry = "" } </PRE></FONT> <h5>Copyright ©1996 by Charles River Media, All Rights Reserved</h5> </BODY> </HTML>